#! /usr/bin/env python
#encoding=utf-8
# -*- python -*-

import sys
sys.path.append("./aima")
sys.path.append("./algoritmos")
sys.path.append("./pygraph")
sys.path.append("./testesJose")
#from grafo import draw_graph

from bfs import breadth_first_tree_search,breadth_first_search
from myutils import mostrarGrafo,custo, draw_graph
from search import romania,GraphProblem
from mapa_australia import australia
from tkgraphview import tkGraphView


py2 = py30 = py31 = False
version = sys.hexversion
if version >= 0x020600F0 and version < 0x03000000 :
    py2 = True    # Python 2.6 or 2.7
    from Tkinter import *
    import ttk
elif version >= 0x03000000 and version < 0x03010000 :
    py30 = True
    from tkinter import *
    import ttk
elif version >= 0x03010000:
    py31 = True
    from tkinter import *
    import tkinter.ttk as ttk
else:
    print ("""
    You do not have a version of python supporting ttk widgets..
    You need a version >= 2.6 to execute PAGE modules.
    """)
    sys.exit()



def vp_start_gui():
    '''Starting point when module is the main routine.'''
    global val, w, root
    root = Tk()
    root.title('Busca Entre Cidades')
    root.geometry('1200x678+615+297')
    set_Tk_var()
    w = Toplevel (root)
    init()
    root.mainloop()

w = None
def create_Toplevel (root):
    '''Starting point when module is imported by another program.'''
    global w, w_win
    if w: # So we have only one instance of window.
        return
    w = Toplevel (root)
    w.title('Busca Entre Cidades')
    w.geometry('1200x678+615+297')
    set_Tk_var()
    w_win = Toplevel (w)
    init()

    return w_win

def destroy_Toplevel ():
    global w
    w.destroy()
    w = None


def set_Tk_var():
    # These are Tk variables used passed to Tkinter and must be
    # defined before the widgets using them are created.
    global combobox_mapa,combobox_origem,combobox_destino,combobox_algoritmo,combobox_modelo
    combobox_mapa = StringVar()
    combobox_origem = StringVar()
    combobox_destino = StringVar()
    combobox_algoritmo = StringVar()
    combobox_modelo = StringVar()

def init():
    pass



class Toplevel:
    def __init__(self, master=None):
        # Set background of toplevel window to match
        # current style
        style = ttk.Style()
        theme = style.theme_use()
        default = style.lookup(theme, 'background')
        master.configure(background=default)


        self.Frame1 = Frame (master)
        self.Frame1.place(relx=0.0,rely=0.0,relheight=1.0,relwidth=1.0)
        self.Frame1.configure(relief=GROOVE)
        self.Frame1.configure(borderwidth="2")
        self.Frame1.configure(relief="groove")

        self.Label_Mapa = Label (self.Frame1)
        self.Label_Mapa.place(relx=0.01,rely=0.92,height=19,width=36)
        self.Label_Mapa.configure(text='''Mapa''')

        self.TCombobox_Mapa = ttk.Combobox (self.Frame1,textvariable=combobox_mapa,state='readonly')
        self.TCombobox_Mapa.place(relx=0.01,rely=0.95,height=19
                ,width=80)
        self.TCombobox_Mapa.configure(takefocus="")
        value_list = ['Romenia','Australia']
        self.TCombobox_Mapa.configure(values=value_list)
        self.TCombobox_Mapa.bind('<<ComboboxSelected>>', self._update_values_mapa)
        self.TCombobox_Mapa.current(0)


        self.TCombobox_Origem = ttk.Combobox (self.Frame1,textvariable=combobox_origem,state='readonly')
        self.TCombobox_Origem.place(relx=0.11,rely=0.95,height=19
                ,width=140)
        self.TCombobox_Origem.configure(takefocus="",values=sorted(romania.locations.keys()))
        self.TCombobox_Origem.current(0)


        self.Label_Origem = Label (self.Frame1)
        self.Label_Origem.place(relx=0.11,rely=0.92,height=19,width=46)
        self.Label_Origem.configure(text='''Origem''')

        self.TCombobox_Destino = ttk.Combobox (self.Frame1,textvariable=combobox_destino,state='readonly')
        self.TCombobox_Destino.place(relx=0.264,rely=0.95,height=19,width=140)
        self.TCombobox_Destino.configure(takefocus="",values=sorted(romania.locations.keys()))
        self.TCombobox_Destino.current(0)

        self.Label_Destino = Label (self.Frame1)
        self.Label_Destino.place(relx=0.264,rely=0.92,height=19,width=46)
        self.Label_Destino.configure(text='''Destino''')

        self.TCombobox_Algoritmo = ttk.Combobox (self.Frame1,textvariable=combobox_algoritmo,state='readonly')
        self.TCombobox_Algoritmo.place(relx=0.418,rely=0.95,height=19
                ,width=280)
        vals=['Busca em Largura','Busca em Profundidade']
        self.TCombobox_Algoritmo.configure(takefocus="",values=vals)
        self.TCombobox_Algoritmo.current(0)

        self.Label_Modelo = Label (self.Frame1)
        self.Label_Modelo.place(relx=0.6985,rely=0.92,height=19,width=60)
        self.Label_Modelo.configure(text='''Modelo''')

        self.TCombobox_Modelo = ttk.Combobox (self.Frame1,textvariable=combobox_modelo,state='readonly')
        self.TCombobox_Modelo.place(relx=0.6985,rely=0.95,height=19
                ,width=70)
        vals=['Arvore','Grafo']
        self.TCombobox_Modelo.configure(takefocus="",values=vals)
        self.TCombobox_Modelo.current(0)

        self.Label_Algoritmo1 = Label (self.Frame1)
        self.Label_Algoritmo1.place(relx=0.418,rely=0.92,height=19,width=60)
        self.Label_Algoritmo1.configure(text='''Algoritmo''')

        self.TButtonExecutar1 = ttk.Button (self.Frame1)
        self.TButtonExecutar1.place(relx=0.88,rely=0.95,height=25,width=76)
        self.TButtonExecutar1.configure(command=self.executar)
        self.TButtonExecutar1.configure(takefocus="")
        self.TButtonExecutar1.configure(text='''Executar''')

        self.Scrolledtext1 = ScrolledText (self.Frame1)
        self.Scrolledtext1.place(relx=0.50,rely=0.0,relheight=0.92,relwidth=0.50)

        self.Scrolledtext1.configure(background="white")
        global canvas
        canvas  = Canvas (self.Frame1)
        canvas.place(relx=0.0,rely=0.0,relheight=0.92
                ,relwidth=0.50)
        canvas.configure(borderwidth="2",width=600,height=600)
        #canvas.configure(relief="ridge")



    def write(self, txt):
        #self.text1.insert(INSERT, txt)
        self.Scrolledtext1.insert(INSERT, txt)

    def executar(self):
        sys.stdout = self
        self.buscaCidade()
        #test_script.HelloWorld()
        sys.stdout = sys.__stdout__
        ## sys.stderr = __stderr__

    def buscaCidade(self):
        '''Funcão executada ao pressionar o "botão executar" pega os valores para o mapa
        , a cidade de partida e o objetivo em cima do modelo árvore ou grafo, valores ob-
        tidos pelos conteúdos dos combos'''

        if combobox_mapa.get()=='Romenia':
            mapa=romania
        else:
            mapa=australia

        if combobox_algoritmo.get()=='Busca em Largura':
            if combobox_modelo.get()=='Arvore':
                algoritmo=breadth_first_tree_search
            elif combobox_modelo.get()=='Grafo':
                algoritmo=breadth_first_search
            else:
                pass

        ab=GraphProblem(combobox_origem.get(),combobox_destino.get(),mapa)
        print 'De',combobox_origem.get(),'à',combobox_destino.get(),'(',combobox_algoritmo.get(),'em',combobox_modelo.get(),')'

        # o resultado (retorno do algoritmo) é uma lista do tipo:
        #[Nó,[l ista de nós expandidos]]
        resultado=algoritmo(ab)
        [solution,tree,extendidos]=[resultado[0].solution(),resultado[1],resultado[2]]
#        if len(tree)>6:
#            tree=tree[0:6]
        print combobox_modelo.get(),'de busca:'
        mostrarGrafo(tree, ab)
        print "Solução:",solution
        print "Número de nós extendidos:",extendidos
        try:
            print "Custo Total do Caminho: ",custo(ab, solution,mapa),"\n"
            node_edge_old_style=draw_graph(tree, mapa, solution, ab)

            tkGraphView(node_edge_old_style, "Graph Viewer Title", root=root, canv=canvas,graphtype='directed',startTk=False)


        except:
            pass

    def _update_values_mapa(self, evt):
        # add entered text to combobox list of values
        widget = evt.widget           # get widget
        val = widget.get()  # get values

        if val=='Romenia':
            vals=sorted(romania.locations.keys())

            self.TCombobox_Origem.configure(values = vals,)
            self.TCombobox_Destino.configure(values = vals,)
        else:
            vals=sorted(australia.dict.keys())
            self.TCombobox_Origem.configure(values = vals,)
            self.TCombobox_Destino.configure(values = vals,)
        self.TCombobox_Origem.current(0)
        self.TCombobox_Destino.current(0)

        return 'break'  # don't propagate event

# The following code is added to facilitate the Scrolled widgets you specified.
class AutoScroll(object):
    '''Configure the scrollbars for a widget.'''

    def __init__(self, master):
        vsb = ttk.Scrollbar(master, orient='vertical', command=self.yview)
        hsb = ttk.Scrollbar(master, orient='horizontal', command=self.xview)

        self.configure(yscrollcommand=self._autoscroll(vsb),
            xscrollcommand=self._autoscroll(hsb))
        self.grid(column=0, row=0, sticky='nsew')
        vsb.grid(column=1, row=0, sticky='ns')
        hsb.grid(column=0, row=1, sticky='ew')

        master.grid_columnconfigure(0, weight=1)
        master.grid_rowconfigure(0, weight=1)

        # Copy geometry methods of master  (took from ScrolledText.py)
        if py31:
            methods = Pack.__dict__.keys() | Grid.__dict__.keys() \
                  | Place.__dict__.keys()
        else:
            methods = Pack.__dict__.keys() + Grid.__dict__.keys() \
                  + Place.__dict__.keys()

        for meth in methods:
            if meth[0] != '_' and meth not in ('config', 'configure'):
                setattr(self, meth, getattr(master, meth))

    @staticmethod
    def _autoscroll(sbar):
        '''Hide and show scrollbar as needed.'''
        def wrapped(first, last):
            first, last = float(first), float(last)
            if first <= 0 and last >= 1:
                sbar.grid_remove()
            else:
                sbar.grid()
            sbar.set(first, last)
        return wrapped

    def __str__(self):
        return str(self.master)

def _create_container(func):
    '''Creates a ttk Frame with a given master, and use this new frame to
    place the scrollbars and the widget.'''
    def wrapped(cls, master, **kw):
        container = ttk.Frame(master)
        return func(cls, container, **kw)
    return wrapped

class ScrolledText(AutoScroll, Text):
    '''A standard Tkinter Text widget with scrollbars that will
    automatically show/hide as needed.'''
    @_create_container
    def __init__(self, master, **kw):
        Text.__init__(self, master, **kw)
        AutoScroll.__init__(self, master)

if __name__ == '__main__':
    vp_start_gui()



